<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>跳一跳</title>
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
        overflow: hidden;
      }

      #score {
        font-size: 50px;
        color: #fff;
        position: fixed;
        top: 10%;
        left: 10%;
      }

      #fail {
        position: fixed;
        background: rgba(0, 0, 0, 0.5);
        left: 0;
        right: 0;
        width: 100%;
        height: 100%;
        font-size: 70px;
        color: #fff;
        padding-left: 30%;
        padding-top: 200px;
        display: none;
      }
    </style>
    <script src="https://www.unpkg.com/three@0.154.0/build/three.js"></script>
  </head>
  <body>
    <div id="score">得分：0</div>
    <div id="fail">游戏结束，您的分数为：<span id="score2">0</span></div>
    <script>
      const width = window.innerWidth
      const height = window.innerHeight
      const renderer = new THREE.WebGLRenderer({ antialias: true })
      renderer.setSize(width, height)
      renderer.setClearColor(0x333333)

      const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000)
      const scene = new THREE.Scene()
      camera.position.set(100, 100, 100)
      camera.lookAt(scene.position)

      const pointLight = new THREE.DirectionalLight(0xffffff)
      pointLight.position.set(40, 100, 60)
      scene.add(pointLight)

      // const axesHelper = new THREE.AxesHelper(1000)
      // axesHelper.position.set(0, 0, 0)
      // scene.add(axesHelper)

      document.body.appendChild(renderer.domElement)

      function createCube(x, z) {
        const geometry = new THREE.BoxGeometry(30, 20, 30)
        const material = new THREE.MeshPhongMaterial({ color: 0xffffff })
        const cube = new THREE.Mesh(geometry, material)
        cube.position.x = x
        cube.position.z = z
        scene.add(cube)
      }

      function createPlayer() {
        const geometry = new THREE.BoxGeometry(5, 20, 5)
        const material = new THREE.MeshPhongMaterial({ color: 0xffff00 })
        const player = new THREE.Mesh(geometry, material)
        player.position.x = 0
        player.position.y = 17.5
        player.position.z = 0
        scene.add(player)
        return player
      }

      const playerPos = { x: 0, y: 17.5, z: 0 }
      const targetPlayerPos = { x: 0, y: 17.5, z: 0 }
      let player
      let speed = 0
      let score = -1

      player = createPlayer()

      let stopped = true

      function movePlayer() {
        player.position.y += speedY

        if (player.position.y < 17.5) {
          player.position.y = 17.5

          if (stopped === false) {
            if (playerInCube()) {
              score++
              document.querySelector('#score').innerHTML = '得分：' + score

              const distance = Math.floor(50 + Math.random() * 100)
              const num = Math.random()
              if (num > 0.5) {
                direction = 'right'
                currentCubePos.z -= distance
              } else {
                direction = 'left'
                currentCubePos.x -= distance
              }
              createCube(currentCubePos.x, currentCubePos.z)
            } else {
              document.querySelector('#fail').style.display = 'block'
              document.querySelector('#score2').innerHTML = score

              document.body.removeEventListener('mousedown', mousedownFn)
              document.body.removeEventListener('mouseup', mouseupFn)
            }
          }
          stopped = true
        } else {
          stopped = false
          if (direction === 'right') {
            player.position.z -= speed
          } else {
            player.position.x -= speed
          }
        }
        speedY -= 0.3
      }

      const targetCameraPos = { x: 100, y: 100, z: 100 }
      const cameraFocus = { x: 0, y: 0, z: 0 }
      const targetCameraFocus = { x: 0, y: 0, z: 0 }

      function moveCamera() {
        if (player.position.y > 17.5) {
          if (direction === 'right') {
            camera.position.z -= speed
            cameraFocus.z -= speed
          } else {
            camera.position.x -= speed
            cameraFocus.x -= speed
          }

          camera.lookAt(cameraFocus.x, cameraFocus.y, cameraFocus.z)
        }
      }

      const currentCubePos = { x: 0, y: 0, z: 0 }
      let direction = 'right'

      const mousedownFn = () => {
        speed = 0
        speedY = 0
        pressed = true
      }

      const mouseupFn = () => {
        pressed = false
      }

      document.body.addEventListener('mousedown', mousedownFn)
      document.body.addEventListener('mouseup', mouseupFn)

      let pressed = false
      let speedY = 0

      function speedUp() {
        if (pressed) {
          speed += 0.1
          speedY += 0.1

          if (player.scale.y > 0) {
            player.scale.y -= 0.001
          }
          player.position.y -= 15 - 15 * player.scale.y

          if (player.position.y < 10) {
            player.position.y = 10
          }
        } else {
          player.scale.y = 1
        }
      }

      function playerInCube() {
        if (direction === 'right') {
          if (
            player.position.z < currentCubePos.z + 15 &&
            player.position.z > currentCubePos.z - 15
          ) {
            return true
          }
        } else if (direction === 'left') {
          if (
            player.position.x < currentCubePos.x + 15 &&
            player.position.x > currentCubePos.x - 15
          ) {
            return true
          }
        }
        return false
      }

      function render() {
        if (!pressed) {
          moveCamera()
          movePlayer()
        }
        speedUp()

        renderer.render(scene, camera)
        requestAnimationFrame(render)
      }

      createCube(0, 0)
      render()
    </script>
  </body>
</html>
